package com.innovation.ic.b1b.framework.aop;

import com.innovation.ic.b1b.framework.helper.LockHelper;
import com.innovation.ic.b1b.framework.util.IdUtil;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;

@Slf4j
@Aspect
public class ZookeeperLockAspect extends AbstractAspect {

    @Pointcut("@annotation(com.innovation.ic.b1b.framework.annotation.ZookeeperLock)")
    public void doLock() {
        log.trace("进入ZookeeperLockAspect类的doLock方法");
    }

    /******************************************** 上锁 *******************************************/
    /**
     * 进入方法前第一个执行
     *
     * @param joinPoint
     * @return
     * @throws Throwable
     */
    @Around("doLock()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        log.debug("进入ZookeeperLockAspect类的around方法");

        try {
            String zookeeperNode = IdUtil.createUUID();
            zookeeperManager.createPersistentNode("/sc-dev/table/inventory/" + zookeeperNode);
            log.debug("创建/sc-dev/table/inventory/" + zookeeperNode);
            LockHelper.getThreadLocal().set(zookeeperNode);
        } catch (Exception e) {
            log.error(e.toString());
            e.printStackTrace();
        }
        return joinPoint.proceed();
    }

    /**
     * 进入方法前第二个执行
     *
     * @param joinPoint
     */
    @Before("doLock()")
    public void beforeMethod(JoinPoint joinPoint) {
        log.trace("进入ZookeeperLockAspect类的beforeMethod方法");
    }

    /**
     * 方法结束前第一个执行
     *
     * @param ret
     */
    @AfterReturning(returning = "ret", pointcut = "doLock()")
    public void doAfterReturning(Object ret) {
        log.trace("进入ZookeeperLockAspect类的doAfterReturning方法");
    }

    /**
     * @param jp
     */
    @AfterThrowing("doLock()")
    public void throwException(JoinPoint jp) {
        log.trace("进入ZookeeperLockAspect类的throwException方法");
    }


    /**
     * 方法结束前第二个执行
     *
     * @param jp
     */
    @After("doLock()")
    public void after(JoinPoint jp) throws Exception {
        log.debug("进入ZookeeperLockAspect类的after方法");

        String zookeeperNode = LockHelper.getThreadLocal().get();
        boolean exists = true;
        while (exists){
            Thread.sleep(100);
            exists = zookeeperManager.exists("/sc-dev/table/inventory/" + zookeeperNode);
        }
    }
}
